package dao

import (
	"context"
	"encoding/json"
	"fmt"
	"inventory/api/inventory"
	"inventory/internal/conf"
	"inventory/internal/constant"
	"inventory/internal/model"
	"inventory/internal/pkg/dada"
	"inventory/internal/pkg/sf"
	"inventory/pkg/ecode"
	"inventory/pkg/log"
	"time"
)

// DadaDelivery 呼叫达达配送
func (d *Dao) DadaDelivery(ctx context.Context, sourceID, shopNo, orderNumber string, price float64,
	address *inventory.AddressInfo, regionCode string) (deliverFee uint64, err error) {
	req := dada.AddOrderRequest{
		ShopNo:          shopNo,
		OriginID:        orderNumber,
		CityCode:        regionCode,
		CargoPrice:      price,
		IsPrepay:        0,
		ReceiverAddress: address.Address,
		ReceiverLat:     address.Lat,
		ReceiverLng:     address.Lng,
		ReceiverPhone:   address.Mobile,
		ReceiverName:    address.Contact,
		Callback:        conf.Conf.Dada.Callback,
	}

	var resp *dada.AddOrderResponse
	if resp, err = d.dada.Order.AddOrder(ctx, sourceID, &req); err != nil {
		if dadaErr, ok := err.(*dada.ErrorResponse); ok {
			err = ecode.AppendMessage(constant.ErrRemoteAPIFailed, dadaErr.Msg)
		}
		return
	}
	return uint64(resp.DeliverFee * 100), nil
}

// SFDelivery 呼叫顺丰配送
func (d *Dao) SFDelivery(ctx context.Context, shopID string, outTradeNo string, order model.ProcessOrder,
	warehouseName string) (tradeNo string, deliverFee uint64, err error) {
	timestamp := time.Now().Unix()
	address := &inventory.AddressInfo{}
	_ = json.Unmarshal(order.AddressInfo, &address)
	var orderDetails []*model.ProcessDetail
	if orderDetails, err = d.FindProcessOrderDetails(ctx, order.ID); err != nil {
		return
	}
	var count int
	details := make([]sf.ProductDetail, 0, len(orderDetails))
	for _, d := range orderDetails {
		if d.ParentID == 0 {
			count++
			r := model.Remark{}
			if err = json.Unmarshal(d.Remark, &r); err != nil {
				return
			}
			details = append(details, sf.ProductDetail{
				ProductName: r.Name,
				ProductNum:  int(d.Quantity),
			})
		}
	}
	req := sf.CreateOrderRequest{
		DevID:           d.sf.DevID,
		ShopID:          shopID,
		ShopType:        1,
		ShopOrderID:     outTradeNo,
		OrderSource:     warehouseName,
		PayType:         1, // 用户支付方式：1-在线支付 0货到付款
		LbsType:         1, // 百度坐标
		RiderPickMethod: 1, // 物流流向
		OrderTime:       timestamp,
		ReturnFlag:      1,
		Remark:          string(order.Remark),
		PushTime:        timestamp,
		Version:         17,
		Receive: sf.Receive{
			UserName:    address.Contact,
			UserPhone:   address.Mobile,
			UserAddress: address.Address,
			UserLng:     fmt.Sprintf("%f", address.Lng),
			UserLat:     fmt.Sprintf("%f", address.Lat),
		},
		OrderDetail: sf.OrderDetail{
			TotalPrice:     order.ProdTrans,
			ProductType:    1,
			UserMoney:      order.ProdTrans,
			ShopMoney:      order.ProdTrans,
			WeightGram:     1,
			ProductNum:     order.ProdCount,
			ProductTypeNum: count,
			ProductDetail:  details,
		},
	}
	var resp *sf.CreateOrderResponse
	if resp, err = d.sf.Order.CreateOrder(ctx, &req); err != nil {
		if sfErr, ok := err.(*sf.ErrorResponse); ok {
			logger := log.FromContext(ctx)
			logger.Infof("%s", err)
			err = ecode.AppendMessage(constant.ErrRemoteAPIFailed, sfErr.ErrorMsg)
		}
		return
	}
	return resp.SfOrderID, uint64(resp.TotalPrice), nil
}

// SFNotifyVerify 顺丰通知请求校验
func (d *Dao) SFNotifyVerify(body, rawSign string) bool {
	sign, _ := d.sf.Sign(body)
	return rawSign == sign
}
